﻿using System;
using System.Data;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace AMS.Inventory.PDA.Helper
{
    public class FormBuilder
    {
        public string PROPERTY = "property", CTL_ATTR_INFO = "CtlAttrInfo", PAGE_RULE = "page_rule", CHECK_CTL_IDS = "CheckCtlIds", CTL_TYPE = "CtlType";

        public string SELECT_PAGE_URL = "SelectPageURL", MEMO = "Memo", OBJ_PRO_HEAD_STRING = "ObjPro_";

        public string CTL_PROPERTY_FRO_OBJCET = "CtlPropertyFroObject", CTL_OBJ_KEY_PAO = "CtlObjKeyPro", CTL_OBJ_SHOW_PAO = "CtlObjShowPro", CTL_OBJ_SHOW_PAO_2 = "CtlObjShowPro2";

        public string KEY_CONTEXT = "KeyContext", KEY_PROPERTY = "KeyProperty", INIT_NOW = "InitNow", CONDITION_STRING = "ConditionString";

        public string INIT_CURR_USER_IFNO = "InitCurrUserInfo", OTHER_CTL_CONTEXT = "OtherCtlContext";

        public string FORMAT_STRING = "FormatString", ASSEMBLY_NAME = "AssemblyName", NAME_SPACE = "NameSpace", COMMAND_NAME = "CommandName";

        public string NAME = "Name", TYPE_NAME = "TypeName", LIST_SQL = "ListSql", SQL = "sql", CLASS_NAME = "ClassName", USER_CTL_PATH = "UserCtlPath", CTL_PRO_INFO = "CtlProInfo", IS_AllOW_UPDATE = "IsAllowUpdate";

        public string LGNORE_SAVE = "LgnoreSave", SET_DATA="SetData", TEXT="Text",INVENTORY_INFO="InventoryInfo";

        protected ObjXmlReader m_XmlReader;
        public FormBuilder(string settingXmlPath)
        {
            m_XmlReader = new ObjXmlReader(settingXmlPath);
            SettingXmlPath = settingXmlPath;
        }

        public Type GetType(string typeName)
        {
            string[] ss = typeName.Split(',');
            if (ss == null || ss.Length != 2)
                return null;
            string typeFullName = ss[0];
            string assemblyName = ss[1];
            Type val = Assembly.Load(assemblyName).GetType(typeFullName);
            return val;
        }
    
        public string SettingXmlPath { get; set; }

        public XmlNodeList GetProNodeList()
        {
            return m_XmlReader.GetChildNodesFromXML(INVENTORY_INFO, PROPERTY);
        }

        public Control FindControl(Form frm, string ctlName)
        {
            foreach (Control c in frm.Controls)
            {
                if (c.Name == ctlName)
                {
                    return c;
                }
            }
            return null;
        }

        public string GetObjBarcodeVal(Form frm)
        {
            string reVal = "";
            const string strName = "Barcode";
            Control c = FindControl(frm,OBJ_PRO_HEAD_STRING + strName);
            if(c!=null)
            {
                PropertyInfo pi = c.GetType().GetProperty(TEXT);
                if (pi != null)
                {
                    object objVal = pi.GetValue(c, null);
                    if (objVal != null)
                        reVal = objVal.ToString();
                }
            }
            return reVal;
        }

        public void CreateFormContext(Form frm,int top,DataRow row)
        {
            XmlNodeList nlPros = GetProNodeList();
            foreach(XmlNode nPro in nlPros)
            {
                CreateProContext(frm, ref top, nPro,row);
            }
            foreach (Control c in frm.Controls)
            {
                if (c.Name.StartsWith(OBJ_PRO_HEAD_STRING))
                {
                    c.Left = m_TextLeft;
                    c.Width = frm.Width - m_TextLeft - 20;
                }
            }
        }
        public int A_FG = 2, H_FG = 6;

        private int m_TextLeft = 0;

        public void SetContralProInfo(Object ctl, XmlNode node)
        {
            string ctlProInfo = m_XmlReader.GetNodeAttributeValue(node, CTL_PRO_INFO, true);

            if (ctlProInfo.Length > 0)
            {
                string[] ss = ctlProInfo.Split(',');
                foreach (string str in ss) 
                {
                    string[] strss = str.Split(':');
                    string proName = strss[0];
                    string proStringValue = strss[1];
                    PropertyInfo cp = ctl.GetType().GetProperty(proName);
                    object val;
                    if (cp.PropertyType.IsEnum)
                        val = Enum.Parse(cp.PropertyType, proStringValue, false);
                    else
                        val = Convert.ChangeType(proStringValue, cp.PropertyType, null);
                    cp.SetValue(ctl, val, null);
                }
            }
        }

        public void CreateProContext(Form frm,ref int top, XmlNode nPro,DataRow row)
        {
            if (row == null || row.Table == null)
                return;
            string strName = m_XmlReader.GetNodeAttributeValue(nPro, NAME, true);
            string strMemo = m_XmlReader.GetNodeAttributeValue(nPro, MEMO, true);
            string ctlType = m_XmlReader.GetNodeAttributeValue(nPro, CTL_TYPE, true);
            string strInitNow = m_XmlReader.GetNodeAttributeValue(nPro, INIT_NOW, true);
            string strFormatString = m_XmlReader.GetNodeAttributeValue(nPro, FORMAT_STRING, true);
            string strIsAllowUpdate = m_XmlReader.GetNodeAttributeValue(nPro, IS_AllOW_UPDATE, true);
            if(!row.Table.Columns.Contains(strName))
                return;
            Type colType = row.Table.Columns[strName].DataType;

            Label lbl = new Label();
            lbl.Name = "Lable_" + strName;
            lbl.Text = strMemo;
            
            double tempFloat = strMemo.Length*lbl.Font.Size*1.5;
            lbl.Width = Convert.ToInt32(tempFloat);
            lbl.Top = top;
            lbl.Left = A_FG;
            Control c=null;
            string strCtlName=OBJ_PRO_HEAD_STRING + strName;
            if (strIsAllowUpdate=="true")
            FrmCheckInfo.updateMsg.Add(strCtlName);
            if (ctlType.Length > 0)
            {
                Type cType = GetType(ctlType);
                if (cType != null)
                {
                   c = (Control)(Activator.CreateInstance(cType));
                }
            }
            else
            {
                if (colType == typeof(bool))
                    c = new CheckBox();
                else if (colType == typeof(DateTime))
                {
                    var txtDate = new TextBox();
                    if (strInitNow == "true")
                    {
                        txtDate.Text = DateTime.Now.ToString(strFormatString);
                    }
                    c = txtDate;
                }
                else
                {
                    c = new TextBox();
                }
            }
            if (c != null)
            {
                c.Name = strCtlName;
                SetContralProInfo(c, nPro);
                c.Top = top;
                c.Left = lbl.Left + lbl.Width + A_FG;
                if (m_TextLeft < c.Left)
                    m_TextLeft = c.Left;
                c.Width = 100;
                frm.Controls.Add(lbl);
                frm.Controls.Add(c);
            }
            top = lbl.Height + top + H_FG;
        }

        public void SetFormObjInfo(DataRow row,Form frm)
        {
            XmlNodeList nlPros = GetProNodeList();
            foreach (XmlNode nPro in nlPros)
            {
                SetFormObjProInfo(row,nPro,frm);
            }
        }

        public void SetFormObjProInfo(DataRow row,XmlNode proNode,Form frm)
        {
            if (row == null || row.Table == null)
                return;
            string strName = m_XmlReader.GetNodeAttributeValue(proNode, NAME,true);
            if(row.Table.Columns.Contains(strName))
            {
                object objProVal = row[strName];
                Control c = FindControl(frm,OBJ_PRO_HEAD_STRING+strName);
                if(c!=null)
                {
                    SetContralProInfo(c, proNode);
                    PropertyInfo pi = c.GetType().GetProperty(TEXT);
                    if (pi != null)
                    {
                        pi.SetValue(c, Convert.ChangeType(objProVal,pi.PropertyType,null), null);
                    }
                }
            }
        }
    }
}
